package com.reggie.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.reggie.acl.dataobject.Employee;
import com.reggie.acl.mapper.EmployeeMapper;
import com.reggie.common.enums.ResponseCode;
import com.reggie.common.exception.ReggieException;
import com.reggie.common.util.AssertUtils;
import com.reggie.service.model.request.EmployeeLoginRequest;
import com.reggie.service.model.request.EmployeePageRequest;
import com.reggie.service.model.request.EmployeeSaveRequest;
import com.reggie.service.model.request.EmployeeUpdateRequest;
import com.reggie.service.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.Optional;

/**
 * <p>
 * 员工信息 服务实现类
 * </p>
 *
 * @author yth
 * @since 2023-02-04
 */
@Slf4j
@Service
public class EmployeeServiceImpl implements EmployeeService {

    @Autowired
    private EmployeeMapper employeeMapper;

    @Override
    public Employee login(EmployeeLoginRequest dto) {
        // 查询用户
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Employee::getUsername, dto.getUsername());
        Employee selectEmp = employeeMapper.selectOne(wrapper);
        if (selectEmp == null) {
            throw new ReggieException(ResponseCode.CLIENT_ERROR, "登入失败，用户名不存在");
        }
        // 判断密码
        String encodedPwd = DigestUtils.md5DigestAsHex(dto.getPassword().getBytes());
        if (!encodedPwd.equals(selectEmp.getPassword())) {
            throw new ReggieException(ResponseCode.CLIENT_ERROR, "登入失败，密码错误");
        }
        // 判断状态
        if (selectEmp.getStatus() == 0) {
            throw new ReggieException(ResponseCode.CLIENT_ERROR, "登入失败，该账号已被禁用");
        }
        // 登入成功
        return selectEmp;
    }

    @Override
    public Page<Employee> page(EmployeePageRequest dto) {
        // 对于昵称进行模糊匹配
        LambdaQueryWrapper<Employee> wrapper = Wrappers.lambdaQuery(Employee.class)
                .like(StringUtils.isNotBlank(dto.getName()), Employee::getName, dto.getName())
                .orderByDesc(Employee::getUpdateTime);

        return employeeMapper.selectPage(new Page<>(dto.getPage(), dto.getPageSize()), wrapper);
    }

    @Override
    public void saveEmployee(EmployeeSaveRequest request) {
        AssertUtils.nonNull(request, ResponseCode.CLIENT_ERROR);
        AssertUtils.nonNull(request.getUsername(), ResponseCode.CLIENT_ERROR);

        // 校验员工用户名唯一
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Employee::getUsername, request.getUsername());
        int count = employeeMapper.selectCount(wrapper);
        if (count > 0) {
            throw new ReggieException(ResponseCode.CLIENT_ERROR, "添加员工失败，员工用户名已存在");
        }
        // 创建者信息，创建时间 -> MyMetaObjectHandler
        Employee employee = toEntity(request);
        employee.setStatus(1);  // 默认状态正常
        // 默认密码为123456（密码长度必须>=6）
        byte[] bytes = "123456".getBytes();
        employee.setPassword(DigestUtils.md5DigestAsHex(bytes));

        if (employeeMapper.insert(employee) <= 0) {
            log.error("数据库服务保存员工失败, request: {}", request);
            throw new ReggieException(ResponseCode.SERVER_ERROR, "数据库服务保存员工失败");
        }
    }

    @Override
    public boolean update(EmployeeUpdateRequest request) {
        AssertUtils.nonNull(request, ResponseCode.CLIENT_ERROR);
        AssertUtils.nonNull(request.getId(), ResponseCode.CLIENT_ERROR);

        Employee employee = toEntity(request);
        // 更新者、时间信息 -> MyMetaObjectHandler
        if (employeeMapper.updateById(employee) <= 0) {
            log.error("数据库修改员工失败, request: {}", request);
            throw new ReggieException(ResponseCode.SERVER_ERROR, "数据库修改员工失败");
        }
        return true;
    }

    @Override
    public Optional<Employee> getById(long id) {
        return Optional.ofNullable(employeeMapper.selectById(id));
    }

    private static Employee toEntity(EmployeeSaveRequest dto) {
        if (dto == null) {
            return null;
        }
        Employee employee = new Employee();
        employee.setName(dto.getName());
        employee.setUsername(dto.getUsername());
        employee.setSex(dto.getSex());
        employee.setPhone(dto.getPhone());
        employee.setIdNumber(dto.getIdNumber());
        return employee;
    }

    private static Employee toEntity(EmployeeUpdateRequest dto) {
        if (dto == null) {
            return null;
        }
        Employee employee = new Employee();
        employee.setId(dto.getId());
        employee.setName(dto.getName());
        employee.setUsername(dto.getUsername());
        employee.setSex(dto.getSex());
        employee.setPhone(dto.getPhone());
        employee.setIdNumber(dto.getIdNumber());
        return employee;
    }
}
